/*!
 Temelia - Matrix samples.

 Copyright (C) 2008 Ceata (http://ceata.org/proiecte/temelia).

 @author Dascalu Laurentiu

 This program is free software; you can redistribute it and
 modify it under the terms of the GNU General Public License
 as published by the Free Software Foundation; either version 3
 of the License, or (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

#include "include/samples.h"
#include <temelia/matrix.h>

typedef struct
{
	int currentColumn;
	int columns;
} matrix_context;

matrix_context context;

static void int_matrix_handler(void *key, void *context)
{
	matrix_context *__context = (matrix_context *) context;

	if (key)
		int_handler(key, NULL);
	else
		printf("NULL ");

	if (__context->currentColumn == __context->columns - 1)
	{
		printf("\n");
		__context->currentColumn = 0;
	}
	else
		__context->currentColumn++;
}

static void sample1()
{
	int *x, i, j, n, m;
	matrix_t mat = NULL, copy;

	PRINT("\n\n Sample 1 started \n\n");

	n = 4;
	m = 5;
	x = int_new(10);

	mat = matrix_new(m, n);

	for (i = 0; i < m; i++)
		for (j = 0; j < n; j++)
			matrix_set_key_at(mat, i, j, x);

	context.columns = n;
	context.currentColumn = 0;
	matrix_iterate(mat, int_matrix_handler, &context);
	PRINT("\n\n");

	copy = matrix_clone(mat);

	context.currentColumn = 0;
	matrix_iterate(copy, int_matrix_handler, &context);

	matrix_delete(mat);
	matrix_delete(copy);
	free(x);

	PRINT("\n\n Sample 1 ended \n\n");
}

static void sample2()
{
	int *x, i, j, n, m;
	void **data;
	matrix_t mat = NULL, transposed;

	PRINT("\n\n Sample 2 started \n\n");

	n = 4;
	m = 5;
	mat = matrix_new(m, n);

	for (i = 0; i < m; i++)
		for (j = 0; j < n; j++)
		{
			x = int_new(i * j + 1);
			matrix_set_key_at(mat, i, j, x);
		}

	matrix_iterate(mat, int_matrix_handler, &context);
	transposed = matrix_transpose(mat);
	PRINT("\nTransposed matrix : \n");
	matrix_iterate(transposed, int_matrix_handler, &context);
	PRINT("\n");

	PRINT("Swapping columns 0 and 1\n");
	matrix_swap_columns(mat, 0, 1);
	matrix_iterate(mat, int_matrix_handler, &context);
	PRINT("\n\n");

	PRINT("Swapping rows 1 and 2\n");
	matrix_swap_rows(mat, 1, 2);
	matrix_iterate(mat, int_matrix_handler, &context);
	PRINT("\n\n");

	// Restore default.
	matrix_swap_columns(mat, 0, 1);
	matrix_swap_rows(mat, 1, 2);

	PRINT("Row 1 : ");
	data = matrix_get_row(mat, 1);
	for (i = 0; i < matrix_get_columns_number(mat); i++)
		PRINT("%d ", *(int *) data[i]);
	free(data);
	PRINT("\n\n");

	PRINT("Column 2 : ");
	data = matrix_get_column(mat, 2);
	for (i = 0; i < matrix_get_rows_number(mat); i++)
		PRINT("%d ", *(int *) data[i]);
	free(data);
	PRINT("\n\n");

	matrix_iterate(mat, int_delete, NULL);
	matrix_delete(mat);
	matrix_delete(transposed);

	PRINT("\n\n Sample 2 ended \n\n");
}

static void sample3()
{
	int m = 4, n = 5, i, j;
	matrix_t mat = matrix_new(m, n);

	for (i = 0; i < m; i++)
		for (j = 0; j < n; j++)
			matrix_set_key_at(mat, i, j, int_new(i * n + j));

	context.columns = n;
	context.currentColumn = 0;
	matrix_iterate(mat, int_matrix_handler, &context);
	PRINT("\n\n");

	n = 10;
	matrix_resize(mat, 5, n);

	context.columns = n;
	context.currentColumn = 0;
	matrix_iterate(mat, int_matrix_handler, &context);
	PRINT("\n\n");

	matrix_iterate(mat, int_delete, NULL);

	matrix_delete(mat);
}

void run_matrix_samples()
{
	sample1();
	sample2();
	sample3();
}
